package generate

import (
	"errors"
	"github.com/rs/xid"
	"gopkg.in/yaml.v3"
	"io"
	v1 "k8s.io/api/core/v1"
	v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
	"operator/cicd/util"
)

type ServiceGenerator struct {
	config *util.CICDConfig
}

func (sg *ServiceGenerator) Generate(buf []byte, w io.Writer) (int, error) {
	template := new(ServiceTemplate)
	err := yaml.Unmarshal(buf, template)
	if err != nil {
		return 0, err
	}

	id := sg.config.ID
	if template.Name == "" {
		template.Name = "svc-" + xid.New().String()[:5]
	}
	if template.NameSpace == "" {
		template.NameSpace = "default"
	}
	if template.ServiceType == "" {
		template.ServiceType = "NodePort"
	}
	if len(template.Ports) == 0 {
		return 0, errors.New("ports must be not empty")
	}

	ps := make([]v1.ServicePort, 0, 10)
	if len(template.Ports) > 0 {
		for _, port := range template.Ports {
			pt := v1.ServicePort{}
			pt.Port = port.Port
			pt.Protocol = v1.Protocol(port.Protocol)
			pt.NodePort = port.NodePort
			pt.AppProtocol = port.AppProtocol
			pt.TargetPort = intstr.FromInt(int(port.TargetPort))
			ps = append(ps, pt)
		}
	}

	svc := v1.Service{
		ObjectMeta: v12.ObjectMeta{
			Name: template.Name,
		},
		Spec: v1.ServiceSpec{
			Selector: map[string]string{
				"genid": id,
			},
			Type:  v1.ServiceType(template.ServiceType),
			Ports: ps,
		},
	}

	count, err := util.WriteStruct(&svc, w)

	return count, nil
}

func NewServiceGenerator(config *util.CICDConfig) *ServiceGenerator {
	sg := &ServiceGenerator{
		config: config,
	}

	return sg
}
